// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

package escape

import (
	"cmd/compile/internal/base"
	"cmd/compile/internal/ir"
	"cmd/compile/internal/typecheck"
	"cmd/compile/internal/types"
)

// TODO（mdempsky）：脱毛不属于逃逸分析，
// 但目前它是一些重写最方便的地方。

// fixRecoverCall将ORECOVER调用重写为ORECOVERFP，
// 添加显式的帧指针参数。
// 如果调用不是OreColve调用，则保持不变。
func fixRecoverCall(call *ir.CallExpr) {
	if call.Op() != ir.ORECOVER {
		return
	}

	pos := call.Pos()

	// FP等于调用者的SP加上FixedFrameSize（）。
	var fp ir.Node = ir.NewCallExpr(pos, ir.OGETCALLERSP, nil, nil)
	if off := base.Ctxt.FixedFrameSize(); off != 0 {
		fp = ir.NewBinaryExpr(fp.Pos(), ir.OADD, fp, ir.NewInt(off))
	}
	// TODO（mdempsky）：将*int32替换为不安全。指针，但不会打乱checkptr。
	fp = ir.NewConvExpr(pos, ir.OCONVNOP, types.NewPtr(types.Types[types.TINT32]), fp)

	call.SetOp(ir.ORECOVERFP)
	call.Args = []ir.Node{typecheck.Expr(fp)}
}
